package com.twl.core.framework.dao;

import java.io.Serializable;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

import com.twl.app.base.util.CryptUtils;
import com.twl.core.framework.page.ExpResult;
import com.twl.core.framework.page.Page;
import com.twl.core.framework.page.PagedStatement;
import com.twl.core.framework.page.Result;
import com.twl.core.framework.util.ContextContainer;
@Repository("wSHibernateDaoSupportProxy")
public class WSHibernateDaoSupportProxy extends HibernateDaoSupport {
	
	public Logger log = Logger.getLogger(WSHibernateDaoSupportProxy.class);
	
	@Autowired
	public void setSessionFactoryOverride(SessionFactory sessionFactory) {
		super.setSessionFactory(sessionFactory);
	}
	
	
	/**
	 * 得到翻页结果
	 * 
	 * @param sql
	 *            查询语句
	 * @param params
	 *            客户端Dao类查询参数
	 * @return 翻页结果
	 */
	public Result getListByPage(String sql, Page page) {
		Object[] params = new Object[]{};
		Query query;
		Query queryCount;
		int totalRecords = 0;
		// Page page = ContextContainer.getCurrentPage();
		if (page == null) {
			page = new Page();
		}
		PagedStatement ps = new PagedStatement(sql, ContextContainer.getCurrentLimit(), params);
		String finalSQL = ps.getQuerySQL();
		// 将多空格变成单空格，这样符合DBMS的缓存规则，并且容易判断GROUP BY，不会因为GROUP__BY双空格判断不出
		while (finalSQL.contains("  ")) {
			finalSQL = finalSQL.replace("  ", " ");
		}
		finalSQL = finalSQL.trim();

		query = getSession().createQuery(finalSQL);
		String countSQL = "select count(*) " + finalSQL;
		if (!finalSQL.trim().toLowerCase().startsWith("from ")) {
			countSQL = "select count(*) " + finalSQL.substring(finalSQL.toLowerCase().indexOf("from"));
		}
		queryCount = getSession().createQuery(countSQL);

		Object[] boundParams = ps.getBoundParams();
		for (int i = 0; i < boundParams.length; i++) {
			query.setParameter(i, boundParams[i]);
			queryCount.setParameter(i, boundParams[i]);
		}
		List<?> Records = queryCount.list();
		if (Records.size() == 1)
			totalRecords = Integer.parseInt(Records.get(0).toString());
		else
			totalRecords = Records.size();

		page.setPage(totalRecords);
		page.setMap(page.getTotalPage());
		query.setFirstResult(page.getBeginIndex());
		query.setMaxResults(page.getEveryPage());
		List<?> list = query.list();
		log.info(" 解密开始......");
		long start = System.currentTimeMillis();
		try {
			list = CryptUtils.decryptNew(list);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		log.info("共解密"+list.size()+"条记录"+"耗时"+(System.currentTimeMillis()-start)+"毫秒...");
		
		//ContextContainer.setPage(page);
		return new Result(page, list);
	}
	
	
	/**
	 * 导出结果
	 * 
	 * @param sql
	 *            查询语句
	 * @param params
	 *            客户端Dao类查询参数
	 * @return 翻页结果
	 */
	public ExpResult getExpListByPage(String sql, Page page) {
		Object[] params = new Object[]{};
		Query query;
		Query expQuery;
		Query queryCount;
		int totalRecords = 0;
		// Page page = ContextContainer.getCurrentPage();
		if (page == null) {
			page = new Page();
		}
		PagedStatement ps = new PagedStatement(sql, ContextContainer.getCurrentLimit(), params);
		String finalSQL = ps.getQuerySQL();
		// 将多空格变成单空格，这样符合DBMS的缓存规则，并且容易判断GROUP BY，不会因为GROUP__BY双空格判断不出
		while (finalSQL.contains("  ")) {
			finalSQL = finalSQL.replace("  ", " ");
		}
		finalSQL = finalSQL.trim();

		query = getSession().createQuery(finalSQL);
		expQuery = getSession().createQuery(finalSQL);
		
		String countSQL = "select count(*) " + finalSQL;
		if (!finalSQL.trim().toLowerCase().startsWith("from ")) {
			countSQL = "select count(*) " + finalSQL.substring(finalSQL.toLowerCase().indexOf("from"));
		}
		queryCount = getSession().createQuery(countSQL);

		Object[] boundParams = ps.getBoundParams();
		for (int i = 0; i < boundParams.length; i++) {
			query.setParameter(i, boundParams[i]);
			queryCount.setParameter(i, boundParams[i]);
		}
		List<?> Records = queryCount.list();
		if (Records.size() == 1)
			totalRecords = Integer.parseInt(Records.get(0).toString());
		else
			totalRecords = Records.size();

		page.setPage(totalRecords);
		page.setMap(page.getTotalPage());
		query.setFirstResult(page.getBeginIndex());
		query.setMaxResults(page.getEveryPage());
		List<?> list = query.list();
		
		try{
			list = CryptUtils.decryptNew(list);
		}catch(Exception e){
			e.printStackTrace();
		}
		
		List<?> expList = expQuery.list();
		log.info(" 解密开始......");
		long start = System.currentTimeMillis();
		try{
			expList = CryptUtils.decryptNew(expList);
		}catch(Exception e){
			e.printStackTrace();
		}
		log.info("共解密"+expList.size()+"条记录"+"耗时"+(System.currentTimeMillis()-start)+"毫秒...");
		//ContextContainer.setPage(page);
		return new ExpResult(page, list,expList);
	}
	
	/**
	 * 根据hql查询结果
	 * @param hql
	 * @return
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public List list(String hql){
		Query query = getSession().createQuery(hql);
		List list = query.list();
		try{
			list = CryptUtils.decrypt(list);
		}catch(Exception e){
			e.printStackTrace();
		}
		
		return list;
	}
	
	/**
	 * 根据hql查询唯一结果
	 * @param hql
	 * @return
	 */
	public Object uniqueResult(String hql){
		Query query = getSession().createQuery(hql);
		
		Object obj = query.uniqueResult();
		try{
			//obj = CryptUtils.decrypt(obj);
		}catch(Exception e){
			e.printStackTrace();
		}
		return obj;
	}
	
	
	/**
	 * 根据主键查询
	 * @param clazz
	 * @param id
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public Object get(Class clazz, Serializable id){
		
		Object obj = getSession().get(clazz, id);
		try{
			obj = CryptUtils.decrypt(obj);
		}catch(Exception e){
			e.printStackTrace();
		}
		return obj;
	}
	
	/**
	 * 保存或更新
	 * @param o
	 */
	public void saveOrUpdate(Object o){
		 try{
			o = CryptUtils.encrypt(o);
		}catch(Exception e){
			e.printStackTrace();
		} 
		
		getSession().saveOrUpdate(o);
	}
	
	
	/**
	 * 批量删除
	 * @param hql
	 * @param ids
	 * @return
	 */
	public Integer batchDel(String hql,Integer [] ids){
		Query query = getSession().createQuery(hql.toString());
		query.setParameterList("ids", ids);
		return query.executeUpdate();
	}
	
	/**
	 * 更新
	 * @param hql
	 * @return
	 */
	public Integer executeUpdate(String hql){
		Query query = getSession().createQuery(hql.toString());
		return query.executeUpdate();
	}

	/**
	 * 根据参数查询  select * from Table where id in ()
	 * @param hql
	 * @param list
	 * @param param
	 * @return
	 */
//	public List<?> queryByParams(String hql,List<String> list,String param){
//		Query query = getSession().createQuery(hql.toString());
//		query.setParameterList(param, list);
//		return query.list();
//	}
	

}
